package com.taokatao.cardmee.business.cardcrud;

import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.jakewharton.rxbinding.view.RxView;
import com.taokatao.cardmee.BusEvent;
import com.taokatao.cardmee.C;
import com.taokatao.cardmee.R;
import com.taokatao.cardmee.Utils;
import com.taokatao.cardmee.common.widget.AlertDialog;

import net.bozho.easycamera.DefaultEasyCamera;
import net.bozho.easycamera.EasyCamera;

import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class CardEasyCameraActivity extends Activity {

    @BindView(R.id.progress_bar) ProgressBar mProgressBar;

    @BindView(R.id.capture_preview) FrameLayout vCapturePerView;
    @BindView(R.id.i_take) ImageView iTake;
    @BindView(R.id.i_light) ImageView iLight;

    private AlertDialog dlgError;

    private EasyCamera camera;
    private EasyCamera.CameraActions actions;
    private SurfaceView vSurface;

    private boolean isLightMode = false;

    private EasyCamera.PictureCallback callback = new EasyCamera.PictureCallback() {
        public void onPictureTaken(final byte[] data, EasyCamera.CameraActions actions) {
            mProgressBar.setVisibility(View.VISIBLE);
            Observable.fromCallable(new Callable<File>() {
                @Override
                public File call() throws Exception {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                    //旋转图片 动作
                    Matrix matrix = new Matrix();
                    matrix.postRotate(90);
                    // 创建新的图片
                    Bitmap rotated;
                    try {
                        rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                    } catch (OutOfMemoryError e) {
                        e.printStackTrace();
                        return null;
                    }
                    // store picture
                    File fCapturePicture = new File(getExternalCacheDir(), "pic_crop_" + System.currentTimeMillis() + ".jpg");
                    Utils.saveImage(rotated, fCapturePicture.getAbsolutePath());
                    return fCapturePicture;
                }
            }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<File>() {
                @Override
                public void call(File fCapturePicture) {
                    mProgressBar.setVisibility(View.GONE);
                    if (fCapturePicture != null) {
                        Utils.postMainThreadBusEvent(BusEvent.CARD_CAMERA_SAVED, fCapturePicture);
                    } else {
                        Utils.showToast("非常抱歉，生成图片所需的内存不足，请重新尝试");
                    }
                    finish();
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card_easy_camera);
        ButterKnife.bind(this);
        Utils.logd("CardEasyCameraActivity onCreate");

        ImageView viewBack = (ImageView) findViewById(R.id.i_back);
        viewBack.setImageResource(R.mipmap.common_back_white);
        viewBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        vCapturePerView.addView(vSurface = new SurfaceView(this));

        RxView.clicks(iTake).throttleFirst(C.settings.ANIMATION_TIME, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        vSurface.removeCallbacks(runFocus);
                        try {
                            actions.takePicture(EasyCamera.Callbacks.create().withJpegCallback(callback));
                        } catch (Exception e) {
                            // Caused by: java.lang.RuntimeException: Camera is being used after Camera.release() was called
                            e.printStackTrace();
                        }

                    }
                });

        RxView.clicks(vCapturePerView).throttleFirst(C.settings.ANIMATION_TIME, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        if (camera != null) camera.autoFocus(null);
                    }
                });

        RxView.clicks(iLight).throttleFirst(C.settings.ANIMATION_TIME, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        if (camera != null) {
                            Utils.onMobEvent(CardEasyCameraActivity.this, "clickFlashlight");
                            isLightMode = !isLightMode;
                            Camera.Parameters cameraParameters = camera.getParameters();
                            cameraParameters.setFlashMode(isLightMode ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF);
                            camera.setParameters(cameraParameters);
                        }
                    }
                });
    }

    private Runnable runFocus = new Runnable() {
        @Override
        public void run() {
            if (camera != null) {
                try {
                    camera.autoFocus(null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                vSurface.removeCallbacks(runFocus);
                vSurface.postDelayed(runFocus, 3000);
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        try {
            camera = DefaultEasyCamera.open();
        } catch (Exception e) {
            e.printStackTrace();
            showErrorDialog();
            return;
        }
        vSurface.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Utils.logd("CardEasyCameraActivity surfaceCreated");
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Utils.logd("CardEasyCameraActivity surfaceChanged");
                try {
                    camera.alignCameraAndDisplayOrientation(getWindowManager());
                    actions = camera.startPreview(holder);
                } catch (Exception e) {
                    e.printStackTrace();
                    showErrorDialog();
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Utils.logd("CardEasyCameraActivity surfaceDestroyed");
            }
        });
        vSurface.postDelayed(runFocus, 2000);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Utils.logd("CardEasyCameraActivity onPause");
        releaseCamera();
    }

    private void releaseCamera() {
        if (camera != null) {
            camera.close();
            camera = null;
            vSurface.removeCallbacks(runFocus);
        }
    }

    private void showErrorDialog() {
        if (dlgError == null) {
            dlgError = new AlertDialog.Builder(this)
                    .setCancelable(false)
                    .setTitle("无法连接到相机")
                    .setMessage("需要赋予访问相机的权限，不开启将无法正常工作！")
                    .setPositiveButton("知道了", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dlgError.dismiss();
                            CardEasyCameraActivity.this.finish();
                        }
                    }).create();
        }

        dlgError.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Utils.logd("CardEasyCameraActivity onDestroy");
    }
}
